/* * funCKit - functional Circuit Kit * Copyright (C) 2013 Lukas Elsner <open@mindrunner.de> * Copyright (C) 2013 Peter Dahlberg <catdog2@tuxzone.org> * Copyright (C) 2013 Julian Stier <mail@julian-stier.de> * Copyright (C) 2013 Sebastian Vetter <mail@b4sti.eu> * Copyright (C) 2013 Thomas Poxrucker <poxrucker_t@web.de> * Copyright (C) 2013 Alexander Treml <alex.treml@directbox.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.sep2011.funckit.view.filechooser; import de.sep2011.funckit.Application; import de.sep2011.funckit.Application.OperatingSystem; import de.sep2011.funckit.util.Log; import de.sep2011.funckit.util.internationalization.Language; import de.sep2011.funckit.view.View; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import java.awt.FileDialog; import java.io.File; /** * The filechooser used for this project. It wraps the JFileChooser and the FileDialog * using the one that better fits the environment the program is started. */ public class FunckitFileChooser { /** * The Swing JFileChooser is used as default because it has more features. */ private JFileChooser fileChooser; /** * The old AWT FileDialog is used to get native file choosers on OSX and WIN. */ private FileDialog fileDialog; /** * Filter for the funCKit format. */ private final AbstractFileFilter fckFormat = new FunckitFileFilter(); /** * Filter for the SEP format. */ private final AbstractFileFilter sepFormat = new SepFileFilter(); /** * Filter for the GIF format. */ private final AbstractFileFilter gifFormat = new GifFileFilter(); /** * Filter for the JPG format. */ private final AbstractFileFilter jpgFormat = new JpgFileFilter(); /** * Filter for the PDF format. */ private AbstractFileFilter pdfFormat; /** * Filter for the PNG format. */ private final AbstractFileFilter pngFormat = new PngFileFilter(); /** * Filter for the SVG format. */ private AbstractFileFilter svgFormat; /** * Filter for the cmp format (used for ComponentTypes). */ private final AbstractFileFilter cmpFormat = new ComponentFileFilter(); /** * The {@link View} used by this filechooser. */ private View view; /** * Use the AWT FileDialog (which is native on some platforms)? */ private final boolean nativeDialog; private enum Mode { LOAD, SAVE, SAVE_AS, SAVE_COMPONENT } /** * Enum for the various file formats. */ public enum FileFormat { /** * FCK: funCKit format, SEP: SEP exchange format, CMP: ComponentType format. */ FCK, SEP, GIF, JPG, PDF, PNG, SVG, CMP, NONE } /** * Creates a new file chooser for the given {@link View}. * @param view the {@link View} to create the file chooser for. */ public FunckitFileChooser(View view) { /* * only use PDF and SVG if Exporter Classes are available */ try { Class.forName("de.sep2011.funckit.converter.PDFExporter"); pdfFormat = new PdfFileFilter(); } catch (ClassNotFoundException e) { Log.gl().info("PDFExporter not availible"); } try { Class.forName("de.sep2011.funckit.converter.SVGExporter"); svgFormat = new SvgFileFilter(); } catch (ClassNotFoundException e) { Log.gl().info("SVGExporter not availible"); } assert view != null; this.view = view; nativeDialog = Application.OS == OperatingSystem.OSX || Application.OS == OperatingSystem.WIN; if (nativeDialog) { fileDialog = new FileDialog(view.getMainFrame()); } else { fileChooser = new JFileChooser(); fileChooser.setAcceptAllFileFilterUsed(false); } } private File[] openDialog(Mode mode) { return openDialog(mode, view.getSessionModel().getCurrentProjectPath()); } private File[] openDialog(Mode mode, String path) { if (!nativeDialog) { fileChooser.resetChoosableFileFilters(); } if (path != null && !path.equals("")) { File dir = new File(path); if (nativeDialog) { fileDialog.setDirectory(path); } else { fileChooser.setCurrentDirectory(dir); } } String title = ""; switch (mode) { case LOAD: { title = "FileDialog.open"; if (nativeDialog) { fileDialog.setFilenameFilter(new LoadFilenameFilter()); } else { fileChooser.addChoosableFileFilter(fckFormat); fileChooser.addChoosableFileFilter(cmpFormat); fileChooser.addChoosableFileFilter(sepFormat); fileChooser.setFileFilter(fckFormat); fileChooser.setMultiSelectionEnabled(true); } break; } case SAVE: { title = "FileDialog.save"; if (nativeDialog) { fileDialog.setFilenameFilter(new SaveFilenameFilter()); } else { fileChooser.addChoosableFileFilter(fckFormat); fileChooser.addChoosableFileFilter(sepFormat); fileChooser.addChoosableFileFilter(gifFormat); fileChooser.addChoosableFileFilter(pdfFormat); fileChooser.addChoosableFileFilter(pngFormat); fileChooser.addChoosableFileFilter(svgFormat); fileChooser.addChoosableFileFilter(jpgFormat); fileChooser.setFileFilter(fckFormat); } break; } case SAVE_AS: { title = "FileDilaog.saveas"; if (nativeDialog) { fileDialog.setFilenameFilter(new SaveFilenameFilter()); } else { fileChooser.addChoosableFileFilter(fckFormat); fileChooser.addChoosableFileFilter(sepFormat); fileChooser.addChoosableFileFilter(gifFormat); fileChooser.addChoosableFileFilter(pdfFormat); fileChooser.addChoosableFileFilter(pngFormat); fileChooser.addChoosableFileFilter(svgFormat); fileChooser.addChoosableFileFilter(jpgFormat); fileChooser.setFileFilter(fckFormat); } break; } case SAVE_COMPONENT: { title = "FileDialog.saveComponent"; if (nativeDialog) { fileDialog.setFilenameFilter(new ComponentFileFilter()); } else { fileChooser.addChoosableFileFilter(cmpFormat); } break; } } if (nativeDialog) { fileDialog.setMode(mode == Mode.LOAD ? FileDialog.LOAD : FileDialog.SAVE); fileDialog.setTitle(Language.tr(title)); fileDialog.setVisible(true); String fileName = fileDialog.getFile(); String directory = fileDialog.getDirectory(); if (fileName == null) { return null; } File[] files = new File[1]; files[0] = new File(directory, fileName); return files; } fileChooser.setDialogTitle(Language.tr(title)); int ret; if (mode == Mode.LOAD) { ret = fileChooser.showOpenDialog(view.getMainRootPane()); } else { ret = fileChooser.showSaveDialog(view.getMainRootPane()); } if (ret == JFileChooser.APPROVE_OPTION) { if (fileChooser.getSelectedFiles().length == 0) { File[] files = new File[1]; files[0] = fileChooser.getSelectedFile(); return files; } return fileChooser.getSelectedFiles(); } return null; } /** * Opens the open file dialog and returns the selected files. * @return Array of all selected files. */ public File[] openFile() { return openDialog(Mode.LOAD); } private File saveDialog(Mode dialogMode) { return saveDialog(dialogMode, null); } private File saveDialog(Mode dialogMode, String path) { File[] files = (path != null) ? openDialog(dialogMode, path) : openDialog(dialogMode); if (files == null || files.length == 0) { return null; } // add right extension if missing FileFormat format = getSelectedFileFormat(files[0]); if (!nativeDialog || format == FileFormat.NONE || format == FileFormat.FCK) { AbstractFileFilter filter = getSelectedFilter(); if (!filter.accept(files[0])) { files[0] = new File(files[0].getAbsolutePath() + "." + filter.getMainExtension()); } } // prompt for overwrite if (files[0].exists()) { int ret = JOptionPane.showOptionDialog(view.getMainRootPane(), "FileDialog.OverwriteDialog.text", "FileDialog.OverwriteDialog.title", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (ret == JOptionPane.NO_OPTION) { return null; } } return files[0]; } /** * Opens the save file dialog and returns the selected file. * @return the selected file. */ public File saveFile() { return saveDialog(Mode.SAVE); } /** * Opens the save file as dialog and returns the selected file. * @return the selected file. */ public File saveFileAs() { return saveDialog(Mode.SAVE_AS); } /** * Opens the save component dialog and returns the selected file. * The start directory is the one used to store the components in * the NewBrickList. * @return the selected file. */ public File saveComponent() { return saveDialog(Mode.SAVE_COMPONENT, view.getSessionModel() .getNewBrickListManager().getExternalTypePath()); } private AbstractFileFilter getSelectedFilter() { if (nativeDialog) { return fckFormat; // default to funckit, because you cannot select one } return (AbstractFileFilter) fileChooser.getFileFilter(); } /** * Checks what {@link FileFormat} was selected. In native mode * this is done by checking what file extension matches the given file. * @param file the file of what the extension is checked in native mode. * @return the selected {@link FileFormat} */ public FileFormat getSelectedFileFormat(File file) { if (nativeDialog) { if (fckFormat.accept(file)) return FileFormat.FCK; if (sepFormat.accept(file)) return FileFormat.SEP; if (gifFormat.accept(file)) return FileFormat.GIF; if (jpgFormat.accept(file)) return FileFormat.JPG; if (pdfFormat.accept(file)) return FileFormat.PDF; if (svgFormat.accept(file)) return FileFormat.SVG; if (pngFormat.accept(file)) return FileFormat.PNG; if (cmpFormat.accept(file)) return FileFormat.CMP; } else { if (fileChooser.getFileFilter() == fckFormat) return FileFormat.FCK; if (fileChooser.getFileFilter() == sepFormat) return FileFormat.SEP; if (fileChooser.getFileFilter() == gifFormat) return FileFormat.GIF; if (fileChooser.getFileFilter() == jpgFormat) return FileFormat.JPG; if (fileChooser.getFileFilter() == pdfFormat) return FileFormat.PDF; if (fileChooser.getFileFilter() == svgFormat) return FileFormat.SVG; if (fileChooser.getFileFilter() == pngFormat) return FileFormat.PNG; if (fileChooser.getFileFilter() == cmpFormat) return FileFormat.CMP; } return FileFormat.NONE; } }